﻿using WeDonekRpc.Helper;

namespace ConsoleApp
{
    public class GoodsSpecSku
    {
        public string SpecKey
        {
            get;
            set;
        }
        public long[] SpecId
        {
            get;
            set;
        }

        public string[] Name
        {
            get;
            set;
        }
    }
    public class GoodsSpec
    {
        public long Id { get; set; }

        /// <summary>
        /// 规格名
        /// </summary>
        public string SpecName { get; set; }

        /// <summary>
        /// 规格图标
        /// </summary>
        public string SpecIcon { get; set; }

        /// <summary>
        /// 排序位
        /// </summary>
        public int Sort { get; set; }
    }
    public class GoodsSpecGroup
    {
        public long Id { get; set; }

        /// <summary>
        /// 组名
        /// </summary>
        public string GroupName { get; set; }

        /// <summary>
        /// 排序位
        /// </summary>
        public int Sort { get; set; }

        /// <summary>
        /// 规格项
        /// </summary>
        public GoodsSpec[] Spec { get; set; }
    }
    internal class Program
    {
        private static void Main (string[] args)
        {
            string json = "[{\"Id\":6931904570328405,\"GroupName\":\"CPU\",\"Sort\":2,\"Spec\":[{\"Id\":6932429436093781,\"SpecName\":\"I9\",\"SpecIcon\":\"\",\"Sort\":1}]},{\"Id\":6602616766465373,\"GroupName\":\"GPU\",\"Sort\":3,\"Spec\":[{\"Id\":6602616766465374,\"SpecName\":\"RTX3070\",\"SpecIcon\":\"\",\"Sort\":2},{\"Id\":6602616766465376,\"SpecName\":\"RTX3060\",\"SpecIcon\":\"\",\"Sort\":3}]},{\"Id\":6602616766465368,\"GroupName\":\"颜色\",\"Sort\":4,\"Spec\":[{\"Id\":6602616766465372,\"SpecName\":\"红色\",\"SpecIcon\":\"\",\"Sort\":1},{\"Id\":6602616766465370,\"SpecName\":\"玫瑰金\",\"SpecIcon\":\"\",\"Sort\":2},{\"Id\":6602616766465369,\"SpecName\":\"蓝色\",\"SpecIcon\":\"http://60.214.107.206:11088/file/read/image/6717146277348629.png\",\"Sort\":3},{\"Id\":6602616766465371,\"SpecName\":\"黑色\",\"SpecIcon\":\"\",\"Sort\":4}]}]";
            GoodsSpecSku[] sku = GetSpecSku(json.Json<GoodsSpecGroup[]>());
            string[] names = sku.Select(c => c.Name.Join('|')).ToArray();
            names.ForEach(c =>
            {
                Console.WriteLine(c);
            });
            Console.WriteLine(sku);
            _ = Console.ReadLine();
        }
        private static Dictionary<long, string> _GetSpecSku (GoodsSpecGroup[] groups)
        {
            Dictionary<long, string> specs = [];
            groups.ForEach(c =>
            {
                c.Spec.ForEach(s =>
                {
                    specs.Add(s.Id, c.GroupName + ":" + s.SpecName);
                });
            });
            return specs;
        }

        private static void _FormatSku (List<GoodsSpecSku> skus, GoodsSpecGroup[] groups, int index, Span<long> spacId)
        {
            int next = index + 1;
            foreach (GoodsSpec spec in groups[index].Spec)
            {
                if (next >= spacId.Length)
                {
                    long[] ids = spacId.ToArray();
                    ids[index] = spec.Id;
                    skus.Add(new GoodsSpecSku
                    {
                        SpecId = ids
                    });
                }
                else
                {
                    spacId[index] = spec.Id;
                    _FormatSku(skus, groups, next, spacId);
                }
            }
        }
        public static GoodsSpecSku[] GetSpecSku (GoodsSpecGroup[] groups)
        {
            Dictionary<long, string> specName = _GetSpecSku(groups);
            int gLen = groups.Length;
            List<GoodsSpecSku> skus = new List<GoodsSpecSku>(20);
            groups[0].Spec.ForEach(c =>
            {
                Span<long> ids = new Span<long>(new long[gLen]);
                ids[0] = c.Id;
                _FormatSku(skus, groups, 1, ids);
            });
            skus.ForEach(c =>
            {
                c.SpecKey = string.Join(',', c.SpecId.OrderBy(a => a)).GetMd5();
                c.Name = c.SpecId.ConvertAll(a => specName[a]);
            });
            return skus.ToArray();
        }
    }
}
